#include "csr.h"
#include "exception.h"
#ifdef CONFIG_UARTLITE
#include "uart_lite.h"
#endif
#ifdef CONFIG_IRQCTRL
#include "irq_ctrl.h"
#endif

#ifdef CONFIG_SPILITE
#include "spi_lite.h"
#endif

#ifdef CONFIG_MALLOC
#include "malloc.h"
#endif

#include "gpio_defs.h"
void gpio_write(uint32_t val)
{
    *((volatile uint32_t *)(0x94000000+GPIO_OUTPUT)) = val;
}

#ifdef CONFIG_MALLOC
static uint8_t _heap[CONFIG_MALLOC_SIZE];
#endif

#define CSR_SIM_CTRL_EXIT (0 << 24)
#define CSR_SIM_CTRL_PUTC (1 << 24)

static void sim_exit(int exitcode)
{
    unsigned int arg = CSR_SIM_CTRL_EXIT | ((unsigned char)exitcode);
    asm volatile ("csrw dscratch,%0": : "r" (arg));
}

static int sim_putc(int ch)
{
    unsigned int arg = CSR_SIM_CTRL_PUTC | (ch & 0xFF);
    asm volatile ("csrw dscratch,%0": : "r" (arg));
    return 0;
}

//-----------------------------------------------------------------
// init:
//-----------------------------------------------------------------
void init(void)
{
#ifdef CONFIG_UARTLITE
    // Setup serial port
    uartlite_init(CONFIG_UARTLITE_BASE);
#endif

    if (0x55555555 == csr_read(mhartid)) {
        // luwei: support verilog simulator display.
        printf_register(sim_putc);
    } else {
        // Register serial driver with printf
        printf_register(uartlite_putc);
    }

#ifdef CONFIG_SPILITE
    spi_init(CONFIG_SPILITE_BASE);
#endif

#ifdef CONFIG_MALLOC
    malloc_init(_heap, CONFIG_MALLOC_SIZE, 0, 0);
#endif

#ifdef CONFIG_IRQCTRL
    irqctrl_init(CONFIG_IRQCTRL_BASE);
#endif
}
